/*
 * @Author: fuhongliang-TSJ hongliang.fu@4d-bios.com
 * @Date: 2025-10-09 13:05:48
 * @LastEditTime: 2025-10-14 16:30:29
 * @LastEditors: fuhongliang-TSJ hongliang.fu@4d-bios.com
 * @Description: 
 * @FilePath: \lc_-esp32_-s3\main\lc\handheld\handheld.c
 * 立创实战派ESP32-S3开发板
 * Copyright (c) 2025 by 4D Bios, All Rights Reserved. 
 */

#include "handheld.h"
#include "bsp_lvgl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_check.h"
#include "pca9557.h"
#include "audio.h"

static const char *TAG = "handheld";

EventGroupHandle_t my_event_group;

// 声明使用的字体
LV_FONT_DECLARE(font_alipuhui20);
// 声明使用的图片
LV_IMG_DECLARE(image_lckfb_logo);
LV_IMG_DECLARE(img_att_icon);
LV_IMG_DECLARE(img_music_icon);
LV_IMG_DECLARE(img_sd_icon);
LV_IMG_DECLARE(img_camera_icon);
LV_IMG_DECLARE(img_wifiset_icon);
LV_IMG_DECLARE(img_btset_icon);
// 声明使用的图片
LV_IMG_DECLARE(image_th_icon);
LV_IMG_DECLARE(image_spr_icon);
LV_IMG_DECLARE(image_mic_icon);
LV_IMG_DECLARE(image_att_icon);
LV_IMG_DECLARE(image_comp_icon);
LV_IMG_DECLARE(image_set_icon);

lv_obj_t *lckfb_logo;

lv_obj_t *main_obj; // 主界面
lv_obj_t *main_text_label; // 主界面 欢迎语
lv_obj_t *icon_in_obj; // 应用界面
int icon_flag = 0; // 标记现在进入哪个应用 在主界面时为0

/* Import music file as buffer */
extern const uint8_t music_pcm_start[] asm("_binary_sword_pcm_start");
extern const uint8_t music_pcm_end[]   asm("_binary_sword_pcm_end");

/**
 * @description: 姿态应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void att_event_handler(lv_event_t *e)
{
    att_app();
}

/**
 * @description: 音乐播放器应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void music_event_handler(lv_event_t *e)
{
    music_app();
}

/**
 * @description: SD卡应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void sd_event_handler(lv_event_t *e)
{
    sd_app();
}

/**
 * @description: 相机应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void camera_event_handler(lv_event_t *e)
{
    camera_app();
}

/**
 * @description: WIFI应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void wifi_event_handler(lv_event_t *e)
{
    wifi_app();
}

/**
 * @description: BT蓝牙应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void bt_event_handler(lv_event_t *e)
{
    bt_app();
}

/**
 * @description: 温湿度应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void th_event_handler(lv_event_t *e)
{
    th_app();
}

/**
 * @description: 弹力球游戏应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void game_event_handler(lv_event_t *e)
{
    game_app();
}

/**
 * @description: 回声器应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void echo_event_handler(lv_event_t *e)
{
    echo_app();
}

/**
 * @description: 水平仪应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void sl_event_handler(lv_event_t *e)
{
    sl_app();
}

/**
 * @description: 指南针应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void comp_event_handler(lv_event_t *e)
{
    comp_app();
}

/**
 * @description: 参数设置应用
 * @param {lv_event_t} *e
 * @return {*}
 */
static void set_event_handler(lv_event_t *e)
{
    set_app();
}

/** 主界面
 * @description: 
 * @return {*}
 */
void lv_main_page()
{
    lvgl_port_lock(0);

    lv_obj_del(lckfb_logo);

    lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x000000), 0); //背景黑色

    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_radius(&style, 10);
    lv_style_set_opa(&style, LV_OPA_COVER);
    lv_style_set_bg_color(&style, lv_color_hex(0x00BFFF));
    lv_style_set_bg_grad_color(&style, lv_color_hex(0x00BF00));
    lv_style_set_bg_grad_dir(&style, LV_GRAD_DIR_VER);
    lv_style_set_border_width(&style, 0);
    lv_style_set_pad_all(&style, 0);
    lv_style_set_width(&style, 320);
    lv_style_set_height(&style, 240);
    
    main_obj = lv_obj_create(lv_scr_act());
    
    lv_obj_add_style(main_obj, &style, 0);
    
    // 显示左上角欢迎语
    main_text_label = lv_label_create(main_obj);
    lv_label_set_text(main_text_label, "欢迎使用立创实战派开发板");
    lv_label_set_long_mode(main_text_label, LV_LABEL_LONG_SCROLL_CIRCULAR);
    lv_obj_set_width(main_text_label, 280);
    lv_obj_set_style_text_font(main_text_label, &font_alipuhui20, 0);
    lv_obj_align_to(main_text_label, main_obj, LV_ALIGN_TOP_LEFT, 8, 5);

    // 显示右上角符号
    lv_obj_t *label_symbol = lv_label_create(main_obj);
    lv_label_set_text(label_symbol, LV_SYMBOL_BLUETOOTH LV_SYMBOL_WIFI);
    lv_obj_set_style_text_font(label_symbol, &lv_font_montserrat_20, 0);
    lv_obj_set_style_text_color(label_symbol, lv_color_hex(0xffffff), 0);
    lv_obj_align_to(label_symbol, main_obj, LV_ALIGN_TOP_RIGHT, -10, 10);

    /* 创建平铺视图页面 */
    lv_obj_t *tileview = lv_tileview_create(main_obj); /* 创建平铺视图 */
    lv_obj_set_style_bg_opa(tileview, LV_OPA_0, 0);    /* 背景透明 */
    lv_obj_remove_style(tileview, NULL, LV_PART_SCROLLBAR); /* 移除滚动条 */

    /* 添加页面 1 */
    lv_obj_t *tile_1 = lv_tileview_add_tile( tileview, 0, 0, LV_DIR_RIGHT );
    /* 添加页面 2 */
    lv_obj_t *tile_2 = lv_tileview_add_tile( tileview, 1, 0, LV_DIR_LEFT );

    // 设置应用图标style
    static lv_style_t btn_style;
    lv_style_init(&btn_style);
    lv_style_set_radius(&btn_style, 16);
    lv_style_set_opa(&btn_style, LV_OPA_COVER);
    lv_style_set_text_color(&btn_style, lv_color_hex(0xffffff)); 
    lv_style_set_border_width(&btn_style, 0);
    lv_style_set_pad_all(&btn_style, 5);
    lv_style_set_width(&btn_style, 80);
    lv_style_set_height(&btn_style, 80);

    // 创建第1个应用图标
    lv_obj_t *btn_icon1 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon1, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon1, lv_color_hex(0x30a830), 0);
    lv_obj_set_pos(btn_icon1, 15, 50);
    lv_obj_add_event_cb(btn_icon1, att_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon1 = lv_img_create(btn_icon1);
    lv_img_set_src(img_icon1, &img_att_icon);
    lv_obj_set_align(img_icon1, LV_ALIGN_CENTER);

    // 创建第2个应用图标
    lv_obj_t *btn_icon2 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon2, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon2, lv_color_hex(0xf87c30), 0);
    lv_obj_set_pos(btn_icon2, 120, 50);
    lv_obj_add_event_cb(btn_icon2, music_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon2 = lv_img_create(btn_icon2);
    lv_img_set_src(img_icon2, &img_music_icon);
    lv_obj_set_align(img_icon2, LV_ALIGN_CENTER);

    // 创建第3个应用图标
    lv_obj_t *btn_icon3 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon3, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon3, lv_color_hex(0x008b8b), 0);
    lv_obj_set_pos(btn_icon3, 225, 50);
    lv_obj_add_event_cb(btn_icon3, sd_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon3 = lv_img_create(btn_icon3);
    lv_img_set_src(img_icon3, &img_sd_icon);
    lv_obj_set_align(img_icon3, LV_ALIGN_CENTER);

    // 创建第4个应用图标
    lv_obj_t *btn_icon4 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon4, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon4, lv_color_hex(0xd8b010), 0);
    lv_obj_set_pos(btn_icon4, 15, 147);
    lv_obj_add_event_cb(btn_icon4, camera_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon4 = lv_img_create(btn_icon4);
    lv_img_set_src(img_icon4, &img_camera_icon);
    lv_obj_set_align(img_icon4, LV_ALIGN_CENTER);

    // 创建第5个应用图标
    lv_obj_t *btn_icon5 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon5, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon5, lv_color_hex(0xcd5c5c), 0);
    lv_obj_set_pos(btn_icon5, 120, 147);
    lv_obj_add_event_cb(btn_icon5, wifi_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon5 = lv_img_create(btn_icon5);
    lv_img_set_src(img_icon5, &img_wifiset_icon);
    lv_obj_set_align(img_icon5, LV_ALIGN_CENTER);

    // 创建第6个应用图标
    lv_obj_t *btn_icon6 = lv_btn_create(tile_1);
    lv_obj_add_style(btn_icon6, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon6, lv_color_hex(0xb87fa8), 0);
    lv_obj_set_pos(btn_icon6, 225, 147);
    lv_obj_add_event_cb(btn_icon6, bt_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t *img_icon6 = lv_img_create(btn_icon6);
    lv_img_set_src(img_icon6, &img_btset_icon);
    lv_obj_set_align(img_icon6, LV_ALIGN_CENTER);

    // 创建第7个应用图标
    lv_obj_t * btn_icon7 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon7, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon7, lv_color_hex(0x30a830), 0);
    lv_obj_set_pos(btn_icon7, 15, 50);
    lv_obj_add_event_cb(btn_icon7, th_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon7 = lv_img_create(btn_icon7);
    lv_img_set_src(img_icon7, &image_th_icon);
    lv_obj_align(img_icon7, LV_ALIGN_CENTER, 0, 0);

    // 创建第8个应用图标
    lv_obj_t * btn_icon8 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon8, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon8, lv_color_hex(0xf87c30), 0);
    lv_obj_set_pos(btn_icon8, 120, 50);
    lv_obj_add_event_cb(btn_icon8, game_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon8 = lv_img_create(btn_icon8);
    lv_img_set_src(img_icon8, &image_spr_icon);
    lv_obj_align(img_icon8, LV_ALIGN_CENTER, 0, 0);

    // 创建第9个应用图标
    lv_obj_t * btn_icon9 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon9, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon9, lv_color_hex(0x008b8b), 0);
    lv_obj_set_pos(btn_icon9, 225, 50);
    lv_obj_add_event_cb(btn_icon9, echo_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon9 = lv_img_create(btn_icon9);
    lv_img_set_src(img_icon9, &image_mic_icon);
    lv_obj_align(img_icon9, LV_ALIGN_CENTER, 0, 0);

    // 创建第10个应用图标
    lv_obj_t * btn_icon10 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon10, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon10, lv_color_hex(0xd8b010), 0);
    lv_obj_set_pos(btn_icon10, 15, 147);
    lv_obj_add_event_cb(btn_icon10, sl_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon10 = lv_img_create(btn_icon10);
    lv_img_set_src(img_icon10, &image_att_icon);
    lv_obj_align(img_icon10, LV_ALIGN_CENTER, 0, 0);

    // 创建第11个应用图标
    lv_obj_t * btn_icon11 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon11, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon11, lv_color_hex(0xcd5c5c), 0);
    lv_obj_set_pos(btn_icon11, 120, 147);
    lv_obj_add_event_cb(btn_icon11, comp_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon11 = lv_img_create(btn_icon11);
    lv_img_set_src(img_icon11, &image_comp_icon);
    lv_obj_align(img_icon11, LV_ALIGN_CENTER, 0, 0);

    // 创建第12个应用图标
    lv_obj_t * btn_icon12 = lv_btn_create(tile_2);
    lv_obj_add_style(btn_icon12, &btn_style, 0);
    lv_obj_set_style_bg_color(btn_icon12, lv_color_hex(0xb87fa8), 0);
    lv_obj_set_pos(btn_icon12, 225, 147);
    lv_obj_add_event_cb(btn_icon12, set_event_handler, LV_EVENT_CLICKED, NULL);

    lv_obj_t * img_icon12 = lv_img_create(btn_icon12);
    lv_img_set_src(img_icon12, &image_set_icon);
    lv_obj_align(img_icon12, LV_ALIGN_CENTER, 0, 0);

    lvgl_port_unlock();
}

/**
 * @description: 开机音乐播放任务
 * @param {void} *para
 * @return {*}
 */
void power_music_task(void *para)
{
    pa_en(1);  // 打开音频输出

    bsp_codec_set_fs(CODEC_PCM_SAMPLE_RATE, CODEC_PCM_BIT_WIDTH, CODEC_PCM_CHANNEL);
    bsp_codec_volume_set(40, NULL);

    bsp_play_music(music_pcm_start, music_pcm_end);

    pa_en(0);  // 关闭音频输出
    
    xEventGroupSetBits(my_event_group, START_MUSIC_COMPLETED);
    vTaskDelete(NULL);
}

/**
 * @description: 主界面任务
 * @param {void} *para
 * @return {*}
 */
void main_page_task(void *para)
{
    // 等待开机音乐播放完成
    xEventGroupWaitBits(my_event_group, START_MUSIC_COMPLETED, pdTRUE, pdFALSE, portMAX_DELAY);
    
    // 进入主界面
    lv_main_page();

    vTaskDelete(NULL);
}

// 设置角度的回调函数
static void set_angle(void *img, int32_t angle)
{
    lv_img_set_angle(img, angle);
    //printf("angle = %"PRId32" \n ", angle);
}

// 开机界面
void lv_gui_start(void)
{
    lvgl_port_lock(0);

    // 显示LOGO
    lckfb_logo = lv_img_create(lv_scr_act());
    lv_img_set_src(lckfb_logo, &image_lckfb_logo);
    lv_obj_center(lckfb_logo);
    lv_img_set_pivot(lckfb_logo, 60, 60);  // 设置图片围绕自己的中心位置旋转

    // 设置旋转动画
    lv_anim_t anim;
    lv_anim_init(&anim);
    lv_anim_set_var(&anim, lckfb_logo);      // 动画变量赋值为logo图片
    lv_anim_set_exec_cb(&anim, set_angle);   // 创建设置角度的回调函数
    lv_anim_set_values(&anim, 0, 3600);      // 设置动画旋转角度的开始值和结尾值
    lv_anim_set_time(&anim, 200);            // 设置转一圈的周期是200毫秒
    lv_anim_set_repeat_count(&anim, 5);      // 设置旋转5次
    lv_anim_start(&anim);

    lvgl_port_unlock();
}

/**
 * @description: 掌机程序
 * @return {*}
 */ 
void handheld(void)
{
    lv_gui_start();

    my_event_group = xEventGroupCreate();

    xTaskCreatePinnedToCore(power_music_task, "power_music_task", 4 * 1024, NULL, 5, NULL, 1);  // 播放开机音乐
    xTaskCreatePinnedToCore(main_page_task, "main_page_task", 12 * 1024, NULL, 5, NULL, 0);      // 主界面任务
}